export async function Simulation() {
  const drawio = this
  const drawioBus = window.$store.state.bus.drawioBus;
  const fzPageArr = window.fzPageArr;

  function getConnectId() {
    var date = new Date();
    var year = date.getFullYear();
    var month = repair(date.getMonth() + 1);
    var day = repair(date.getDate());
    var hour = repair(date.getHours());
    var minute = repair(date.getMinutes());
    var second = repair(date.getSeconds());

    var time = year + month + day + hour + minute + second;

    return time + parseInt(Math.random() * 9999);
  }

  function repair(i) {
    if (i > 0 && i <= 9) {
      return "0" + i;
    } else {
      return i;
    }
  }

  var connectId = getConnectId();

  this.connectId = connectId

  function getWsUrl() {
    var href = window.location.href;
    href = href.substr(0, href.indexOf("?"));
    var wsUrl = href.replace('https', 'ws').replace('http', 'ws').replace('graphSimulation', 'webSocket');
    return `${window.top.g.SimulationReq}/webSocket/${connectId}?access_token=${localStorage.getItem('token')}`
  }

  var websocket = null;

  function createWebSocket() {
    if ('WebSocket' in window) {

    } else {
      alert('该浏览器不支持websocket');
      return
    }

    var wsUrl = getWsUrl();
    var websocket = new WebSocket(wsUrl);

    websocket.onopen = mxUtils.bind(this, function (ev) {
      // console.log('建立连接');
      // console.log(ev);
      // 发送请求，绑定id
      let relationTaskName = window.top.getProjectStore(window.top.$constants.RELATED_TASK_NAME);
      var url = window.top.g.Simulation + '/rhapsody/bindWebConnectId';
      this.$axios.post(url, {
        'modelId': this.modelId,
        "projectId": window.top.getProjectStore(window.top.$constants.TASK_ID),
        "connectId": connectId,
        taskName: window.top.getProjectStore(window.top.$constants.PROJECT_NAME)+ relationTaskName,
      })
    })

    websocket.onclose = function (ev) {
      // console.log('连接关闭');
      // console.log(ev);

      /*        setTimeout(function () {
                  // console.log("需要重连....");
                  createWebSocket();
              }, 1000);*/
    }

    websocket.onmessage = function (ev) {
      // console.log('收到消息=====' , JSON.parse(ev.data));
      const data = ev.data;
      try {
        simulationAnim(JSON.parse(data));
      } catch (error) {
        // window.alert('消息格式错误：',data)
      }
    }
  }


  // 前后端分隔符一致
  var ANIM_MESSAGE_SEPARATOR = "%%";

  var bool = true;
  var modelEntity = this.findModelById(this.modelId);
  if (modelEntity != null) {
    var productId = modelEntity.parent_id;
    var productEntity = await this.findProductById(productId);
    if (productEntity != null) {
      var productName = productEntity.name;
      if (productName.indexOf("-实例状态图") !== -1) {
        bool = true;
      }
    }
  }

  let beforeSateArr = [];
  let pointY = 50;

  let isInitData = false;

  function simulationAnim(data) {
    if (data.type) {
      isInitData = true;

      const state = data.type;
      drawioBus.$emit('stateInfo', state)

      if (state === 'LOG') {
        drawioBus.$emit('simulatLog', data.message + '\r\n');
      }

      //状态转移开始 StateTransId
      if (state === 'TRANSITION_START') {
        // console.log('TRANSITION_START=============', data)
        const i = fzPageArr.findIndex(i => i.name === data.instanceName);
        const stateName = data.lineId;
        const cell = window.fzCellData[i].cellsIdArr[stateName];
        const arr = [];
        arr.push(cell);
        stateEntered(arr, i);
      }

      //状态转移结束'EndTransId
      if (state === 'TRANSITION_END') {
        // console.log('TRANSITION_END==========', data);
        const i = fzPageArr.findIndex(i => i.name === data.instanceName);
        const stateName = data.lineId;
        const cell = window.fzCellData[i].cellsIdArr[stateName];
        const arr = [];
        arr.push(cell);
        // console.log(arr)

        stateExited(arr, i);

        const sourceStateName = data.sourceStateName;
        // console.log(sourceStateName)
        const cell2 = window.fzCellData[i].cellsNameArr[sourceStateName];
        // console.log(cell2)
        beforeSateArr[stateName] = cell2;
        // console.log(beforeSateArr)
      }

      //状态进入 StateEntered
      if (state === 'STATE_ENTER') {
        // console.log('STATE_ENTER==========', data);
        const i = fzPageArr.findIndex(i => i.name === data.instanceName);
        const stateName = data.stateName;
        const cell = window.fzCellData[i].cellsNameArr[stateName];
        const arr = [];
        arr.push(cell);
        // console.log(cell)

        stateEntered(arr, i);
      }

      //状态退出
      if (state === 'STATE_EXIT') {
        // console.log('STATE_EXIT', data)
        let fzIndex = fzPageArr.findIndex(i => i.name === data.instanceName);
        // console.log(fzIndex);
        // if (receivedPartName === window.partName) {
        const stateName = data.stateName;
        // console.log(stateName)
        const cell = window.fzCellData[fzIndex].cellsNameArr[stateName];
        // console.log(cell)
        const arr = [];
        arr.push(cell);
        // console.log(cell)

        const isParent = data.isParent;
        if (isParent) {
          stateDefault(arr, fzIndex);
        } else {
          stateExited(arr, fzIndex);
        }
        // 把前面的线设置成默认状态
        var inLineStr = data.idList;
        if (inLineStr.length) {
          var inLineArr = inLineStr;
          for (var i = 0; i < inLineArr.length; i++) {
            var inLineId = inLineArr[i];
            var cell2 = window.fzCellData[fzIndex].cellsIdArr[inLineId];
            var arr2 = [];
            arr2.push(cell2)
            stateDefault(arr2, fzIndex);

            //  前面的状态设置成默认状态
            // console.log(beforeSateArr)
            var cell3 = beforeSateArr[inLineId];
            if (cell3 != null) {
              var arr3 = [];
              arr3.push(cell3)
              stateDefault(arr3, fzIndex);
            }
          }
        } else {
          var inLineId = inLineStr;
          var cell2 = window.fzCellData[fzIndex].cellsIdArr[inLineId];
          var arr2 = [];
          arr2.push(cell2)
          stateDefault(arr2, fzIndex);

          //  前面的状态设置成默认状态
          var cell3 = beforeSateArr[inLineId];
          if (cell3 != null) {
            var arr3 = [];
            arr3.push(cell3)
            stateDefault(arr3, fzIndex);
          }
        }
        // }
      }

      //时序图-状态进入
      if (state === 'STATE_ENTER') {
        // console.log('时序图-状态进入===================================');
        // console.log(data);
        stateEnterUmlLifeline(data);
      }

      //时序图-发送事件
      if (state === 'EVENT_SENT') {
        // console.log('时序图-发送事件====================================');
        // console.log(data)
        eventSentUmlLifeline(data);
      }

      //时序图-操作
      if (state === 'METHOD_CALL') {
        // console.log('时序图-操作====================================');
        // console.log(data);
        methodCallUmlLifeline(data);
      }

    } else {
      data = data.substring(4);
      if (data === "仿真结束！") {
        window.location = location;
        parent.$('#greetings')[0].innerHTML = "";
      }
      //播放消息
      parent.$('#greetings').append("<tr><td style='background: #333;color: #aaa;float: left;border: none'>" + data + "</td></tr>");
      //滚动条滚动到最低部
      parent.$('#log-container').parent().parent().scrollTop($('#log-container').height());
    }

  }


  window.onbeforeunload = function (e) {
    websocket && websocket.close();
    // console.log("b");
  }

  const stateEntered = function (fireState, i) {
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKEWIDTH, "5", fireState);
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#ff6fb7", fireState);
  }

  const stateExited = function (fireState, i) {
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKEWIDTH, "5", fireState);
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#a3c104", fireState);
  }

  const stateDefault = function (fireState, i) {
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKEWIDTH, "0", fireState);
    window[i].myEditor.editor.graph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#000000", fireState);
  }

  const stateEnterUmlLifeline = function (data) {
    window.fzPageArr.map((item, i) => {
      if (item.isUmlLifeLine) {
        let cells = window.fzUmlLifelineCells[i];
        cells.forEach(cell => {
          if (cell.style && cell.style.indexOf("shape=umlLifeline;") > -1 && cell.value && typeof cell.value !== 'string'){
            // console.log(data)
            // console.log(cell)
            cell.geometry.height = cell.geometry.height + 80;
            const cellName = cell.value.getAttribute("label");
            // if (data['instanceName'].indexOf(cellName) > -1) {
            if (cellName.includes(data['instanceName'])) {
              // if (cellName === data['instanceName']) {
              pointY = pointY + 80;
              const width = cell.geometry.width;
              const height = cell.geometry.height;
              const x = cell.geometry.x;
              const y = cell.geometry.y;
              // 再设置状态进入
              const style = 'shape=hexagon;perimeter=hexagonPerimeter;whiteSpace=wrap；html=1;';
              const hexagonCell = new mxCell(data['stateName'], new mxGeometry(0, 0, 70, 60), style);
              hexagonCell.vertex = true;
              hexagonCell.geometry.x = x + (width - 70) / 2;
              hexagonCell.geometry.y = pointY;
              window[i].myEditor.editor.graph.addCells([hexagonCell]);
              window[i].myEditor.editor.graph.refresh();

              scrollDiv(i);
            }
          }
        })
      }
    });
  }

  const eventSentUmlLifeline = function (data) {
    window.fzPageArr.map((item, i) => {
      if (item.isUmlLifeLine) {
        let cells = window.fzUmlLifelineCells[i];
        // console.log(cells)
        if (data['instanceName'] === data['receiverInstanceName']) {
          // console.log('指向自己-文字')
          eventSentMySelf(data, cells, i);
        } else {
          // console.log('指向其他-箭头')
          eventSentOther(data, cells, i);
        }
      }
    });
  }

  const eventSentMySelf = function (data, cells, i) {
    cells.forEach(cell => {
      if (cell.style && cell.style.indexOf("shape=umlLifeline;") > -1 && cell.value && typeof cell.value !== 'string') {
        cell.geometry.height = cell.geometry.height + 80;
        // console.log('指向自己-文字')
        // console.log(data)
        // console.log(cell)
        const cellName = cell.value.getAttribute("label");
        // if (cellName === data['receiverInstanceName']) {
        if (cellName.includes(data['receiverInstanceName'])) {
          pointY = pointY + 80;
          const width = cell.geometry.width;
          const height = cell.geometry.height;
          const x = cell.geometry.x;
          const y = cell.geometry.y;
          // 再设置状态进入
          const style = 'text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;labelBackgroundColor=#FFFFFF;';
          const textCell = new mxCell(data['eventName'], new mxGeometry(0, 0, 100, 20), style);
          textCell.vertex = true;
          textCell.geometry.x = x + (width - 100) / 2;
          textCell.geometry.y = pointY;
          window[i].myEditor.editor.graph.addCells([textCell]);
          window[i].myEditor.editor.graph.refresh();

          scrollDiv(i);
        }
      }
    })
  }

  const eventSentOther = function (data, cells, i) {
    // console.log(data)
    let senderCell;
    let destCell;
    cells.forEach(cell => {
      if (cell.style && cell.style.indexOf("shape=umlLifeline;") > -1 && cell.value && typeof cell.value !== 'string') {
        cell.geometry.height = cell.geometry.height + 80;
        const cellName = cell.value.getAttribute("label");
        // console.log('指向其他-箭头')
        // console.log(data)
        // console.log(cell)
        // 发送
        // if (cellName === data['instanceName']) {
        if (cellName.includes(data['instanceName'])) {
          senderCell = cell
        }
        // 接收
        // if (cellName === data['receiverInstanceName']) {
        if (cellName.includes(data['receiverInstanceName'])) {
          destCell = cell
        }
      }
    });
    // console.log('指向其他-箭头')
    // console.log(senderCell)
    // console.log(destCell)

    pointY = pointY + 80;

    let x1 = senderCell.geometry.x + senderCell.geometry.width / 2;
    let y1 = pointY;
    let x2 = destCell.geometry.x + destCell.geometry.width / 2;
    let y2 = pointY + 40;

    const style = 'endArrow=classic;html=1;edgeStyle=straightEdgeStyle;entryPerimeter=0;exitPerimeter=0;rounded=0;';
    const arrowCell = new mxCell(data['eventName'], new mxGeometry(0, 0, 100, 40), style);
    arrowCell.vertex = true;
    arrowCell.geometry.setTerminalPoint(new mxPoint(x1, y1), true);
    arrowCell.geometry.setTerminalPoint(new mxPoint(x2, y2), false);
    arrowCell.geometry.relative = true;
    arrowCell.edge = true;
    window[i].myEditor.editor.graph.addCells([arrowCell]);
    window[i].myEditor.editor.graph.refresh();

    scrollDiv(i);
  }

  const methodCallUmlLifeline = function (data) {
    window.fzPageArr.map((item, i) => {
      if (item.isUmlLifeLine) {
        let cells = window.fzUmlLifelineCells[i];
        // console.log(data)
        // console.log(cells)
        cells.forEach(cell => {
          if (cell.style && cell.style.indexOf("shape=umlLifeline;") > -1 && cell.value && typeof cell.value !== 'string'){
            cell.geometry.height = cell.geometry.height + 80;
            const cellName = cell.value.getAttribute("label");
            // if (data['instanceName'].indexOf(cellName) > -1) {
            if (cellName.includes(data['instanceName'])) {
              // if (cellName === data['instanceName']) {
              pointY = pointY + 80;
              const width = cell.geometry.width;
              const height = cell.geometry.height;
              const x = cell.geometry.x;
              const y = cell.geometry.y;
              let x1 = x + width / 2;
              let y1 = pointY;
              // // 再设置状态进入
              const style = 'endArrow=classic;html=1;edgeStyle=straightEdgeStyle;entryPerimeter=0;exitPerimeter=0;rounded=0;';
              const arrowCell = new mxCell(data['methodName'], new mxGeometry(0, 0, 50, 30), style);
              arrowCell.vertex = false;
              arrowCell.geometry.setTerminalPoint(new mxPoint(x1, y1), true);
              arrowCell.geometry.setTerminalPoint(new mxPoint(x1, y1 + 30), false);
              arrowCell.geometry.points = [new mxPoint(x1 + 50, y1), new mxPoint(x1 + 50, y1 + 30)];
              arrowCell.geometry.offset = new mxPoint(50, 3);
              arrowCell.edge = true;
              window[i].myEditor.editor.graph.addCells([arrowCell]);
              window[i].myEditor.editor.graph.refresh();

              scrollDiv(i);
            }
          }
        })
      }
    });
  }

  const scrollDiv = function (i) {
    let ele = window[i].$('.geDiagramContainer')[0];
    let top = window[i].$('.geBackgroundPage').height();
    if (top > 2000) {
      ele.scrollTo({
        top: top - 913,
        behavior: 'smooth',
      });
    }
  }

  return {
    createWebSocket: createWebSocket
  }
}
